#include "Unit.h"

#include <sstream>

namespace OOInterface
{

Unit::Unit() :
	_name(), _id(-1), _aspects(), _xSize(0), _zSize(0), _loc(0,0,0),
	_health(0), _maxHealth(0), _resourceCosts(), _resourceUpkeep(),
	_resourceStorage(), _isBuilt( false ), _isIdle(true), _buildTime(0),
	_isTransportable(false)
{
}

Unit::~Unit()
{
}

std::string Unit::toString() const
{
	std::ostringstream str;
	str << "+=============================================+\n";
	str << "Unit(" << _id << "):\n";
	str << "Name: " << _name << "\n";
	str << "Size: " << _xSize << ", " << _zSize << "\n";
	str << "Location: (" << _loc.toString() << ")\n";
	str << "Health(max): " << _health << "( " << _maxHealth << " )\n";
	str << "Build Time: " << _buildTime << "\n";
	str << "IsTransportable: " << _isTransportable << "\n";

	str << "Number of Aspects: " << _aspects.size() << "\n";
	for( UnitAspects::const_iterator i = _aspects.begin(); i != _aspects.end(); ++i )
		if( (*i) )
			str << "\t" << (*i)->toString() << "\n";

	str << "Resource Costs: \n";
	for( ResourceMap::const_iterator i = _resourceCosts.begin(); i != _resourceCosts.end(); ++i )
		str << "\t" << (*i).first.toString() << ": " << (*i).second << "\n";

	str << "Resource Upkeep: \n";
	for( ResourceMap::const_iterator i = _resourceUpkeep.begin(); i != _resourceUpkeep.end(); ++i )
		str << "\t" << (*i).first.toString() << ": " << (*i).second << "\n";

	str << "Resource Storage: \n";
	for( ResourceMap::const_iterator i = _resourceStorage.begin(); i != _resourceStorage.end(); ++i )
		str << "\t" << (*i).first.toString() << ": " << (*i).second << "\n";

	str << "+=============================================+\n";

	return str.str();
}

void Unit::accept( UnitVisitor& v ) const
{
	v.visitUnit( *this );
	for( UnitAspects::const_iterator i = _aspects.begin(); i != _aspects.end(); ++i )
		(*i)->accept( v );
}

float Unit::getResourceCost( const Resource& r ) const
{
	ResourceMap::const_iterator i = _resourceCosts.find( r );
	return i != _resourceCosts.end() ? (*i).second : 0.0f;
}

float Unit::getResourceUpkeep( const Resource& r ) const
{
	ResourceMap::const_iterator i = _resourceUpkeep.find( r );
	return i != _resourceUpkeep.end() ? (*i).second : 0.0f;
}

float Unit::getResourceStorage( const Resource& r ) const
{
	ResourceMap::const_iterator i = _resourceStorage.find( r );
	return i != _resourceStorage.end() ? (*i).second : 0.0f;
}

float Unit::getResourceGeneration( const Resource& r ) const
{
	ResourceMap::const_iterator i = _resourceGeneration.find( r );
	return i != _resourceGeneration.end() ? (*i).second : 0.0f;
}

void Unit::addResourceCost( const Resource& r, float cost )
{
	_resourceCosts.insert( std::pair< const Resource, float>( r, cost ) );
}

void Unit::addResourceUpkeep( const Resource& r, float upkeep )
{
	_resourceUpkeep.insert( std::pair< const Resource, float>( r, upkeep ) );
}

void Unit::addResourceStorage( const Resource& r, float storage )
{
	_resourceStorage.insert( std::pair< const Resource, float>( r, storage ) );
}

void Unit::addResourceGeneration( const Resource& r, float generation )
{
	_resourceGeneration.insert( std::pair< const Resource, float>( r, generation ) );
}

void Unit::addAspect( ConstUnitAspectPtr aspect )
{
	if(aspect)
	{
		_aspects.push_back( aspect );
		aspect->setParentUnit( this );
	}

}

void Unit::removeAspect( ConstUnitAspectPtr aspect )
{
	for( UnitAspects::iterator i = _aspects.begin(); i != _aspects.end(); ++i )
		if( *i == aspect )
		{
			_aspects.erase( i );
			aspect->setParentUnit( NULL );
		}



}

}
